package deepbrain.simnetwork.util;

import deepbrain.simnetwork.engine.SimEngine;
import deepbrain.simnetwork.engine.SimpleSimEngine;
import deepbrain.simnetwork.exception.SimNetworkRuntimeException;
import deepbrain.simnetwork.loader.NetworkLoader;
import deepbrain.simnetwork.loader.xml.XmlNetworkLoader;
import deepbrain.simnetwork.monitor.DisplayNetworkMonitor;
import deepbrain.simnetwork.monitor.Monitor;
import deepbrain.simnetwork.monitor.SimTaskMonitor;
import deepbrain.simnetwork.network.Network;
import deepbrain.simnetwork.network.NetworkState;
import deepbrain.simnetwork.task.SimulationTask;

public class SimNetwork {

	public static void runNetwork(Network network, NetworkState initState,
			final int steps, boolean stochastic,
			SimTaskMonitor[] monitors) {
		try {
			System.out.println(network);
			SimulationTask task = new SimulationTask(network, initState) {
				@Override
				public void runTask() {
					runForSteps(steps);
				}
			};

			task.setStochastic(stochastic);

			task.addMonitor(new DisplayNetworkMonitor(System.out));
			if (monitors != null)
				for (Monitor<?> monitor : monitors)
					task.addMonitor(monitor);

			SimEngine engine = new SimpleSimEngine();
			engine.runTask(task);
		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	public static void runNetwork(String filePath, NetworkState initState,
			final int steps, boolean stochastic,
			SimTaskMonitor[] monitors) {
		try {
			NetworkLoader loader = new XmlNetworkLoader(filePath);
			Network network = loader.loadNetwork();
			runNetwork(network, initState, steps, stochastic, monitors);
		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

	public static void runNetwork(String filePath, final int steps,
			Iterable<SimTaskMonitor> monitors) {
		try {
			NetworkLoader loader = new XmlNetworkLoader(filePath);
			Network network = loader.loadNetwork();
			System.out.println(network);
			SimulationTask task = new SimulationTask() {
				@Override
				public void runTask() {
					runForSteps(steps);
				}
			};
			task.setNetwork(network);

			task.addMonitor(new DisplayNetworkMonitor(System.out));
			for (SimTaskMonitor monitor : monitors)
				task.addMonitor(monitor);

			SimEngine engine = new SimpleSimEngine();
			engine.runTask(task);
		} catch (Exception e) {
			throw new SimNetworkRuntimeException(e);
		}
	}

}
